#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include "driver/timer.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "esp_intr_alloc.h"
#include "esp_log.h"
#include "my_uart.h"
#include "color_light.h"

static const char *TAG = "my_uart";
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define RD1_BUF_SIZE (1024)

#define TXD_PIN (GPIO_NUM_1)//(GPIO_NUM_4)
#define RXD_PIN (GPIO_NUM_3)//(GPIO_NUM_5)
#define EX_UART_NUM (UART_NUM_0)//(UART_NUM_1)

static QueueHandle_t my_uart_queue;

//static const char *TAG = "uart_events";
//EventGroupHandle_t s_uart_tx_event_group = NULL;
//Event of UART receving data
/*We'd better handler data event fast, there would be much more data events than
other types of events. If we take too much time on data event, the queue might
be full.*/
static void uart_rx_task(void *pvParameters)
{
    uart_event_t event;
    uint16_t i = 0;
    //uint8_t* dtmp = (uint8_t*) malloc(RD1_BUF_SIZE); //freeRTOS中不能使用malloc!!!!
	uint8_t dtmp[512] = {0};//(uint8_t*) pvPortMalloc(RD1_BUF_SIZE);
    //uint16_t packet_len = 0;
    //uint8_t  packet_data[512]={0};
    for(;;) {
		//vTaskDelay(50 / portTICK_PERIOD_MS);
        //Waiting for UART event.
        if(xQueueReceive(my_uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
            array_clear(dtmp, 512);
            switch(event.type) {
                case UART_DATA:
                    //ESP_LOGE(TAG,"\r\nevent.size = %d",event.size);
                    uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
                    //uart protocol decoding
                    uart_protocol_decoding(dtmp,event.size);
                    // packet_len += event.size;
                    // if(packet_len >= (CONFIG_WS2812_LED_NUM*3+6)){
                    //     uart_read_bytes(EX_UART_NUM, dtmp, packet_len, portMAX_DELAY);
                    //     //Uart_protocol_decoding(dtmp,event.size);
                    //     if((dtmp[0]=='A')&&(dtmp[1]=='d')&&(dtmp[2]=='a')){
                    //         for(i=0;i<CONFIG_WS2812_LED_NUM;i++){
                    //             led_strip_set_color(i,dtmp[6+3*i],dtmp[6+3*i+1],dtmp[6+3*i+2]);
                    //         }
                    //         flag_rx_frame_finish = 1;
                    //         ESP_LOGI(TAG,"\r\nframe rx success!!!");
                    //     }
                    //     ESP_LOGI(TAG,"\r\npacket_len = %d",packet_len);
                    //     //ESP_LOG_BUFFER_HEXDUMP(TAG,dtmp,packet_len,ESP_LOG_INFO);
                    //     packet_len = 0;
                    // }
                    //uart_write_bytes(EX_UART_NUM, (const char*) dtmp, event.size);
                    break;
                case UART_FIFO_OVF:    //Event of HW FIFO overflow detected
                case UART_BUFFER_FULL://Event of UART ring buffer full
					ESP_LOGI(TAG, "\r\nxQueueReset(my_uart_queue)!");
                    // If buffer full happened, you should consider encreasing your buffer size
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(my_uart_queue);
                    break;
                case UART_BREAK:
                case UART_PARITY_ERR:
                case UART_FRAME_ERR:
                case UART_PATTERN_DET:
					ESP_LOGE(TAG,"\r\nUart%d event happen:0x%x",EX_UART_NUM,event.type);
                    break;
                default:
                    break;
            }
        }
    }
    //vPortFree(dtmp);
    array_clear(dtmp, 512);
    vTaskDelete(NULL);
}
static void uart_tx_task(void *pvParameters)
{
		//EventBits_t evt_bits = 0;
	    int rx_len = 0;
		uint8_t rx_data[1024] = {0};
		ESP_LOGI(TAG, "esp_uart_tx_task start!!!");
		//s_uart_tx_event_group = xEventGroupCreate();
		// xEventGroupSetBits(s_uart_tx_event_group, UART_TX_EVENT_BIT);
		while (1) {
			vTaskDelay(10 / portTICK_PERIOD_MS);
			//rx_len = uart_read_bytes(EX_UART_NUM, rx_data, 200, 50 / portTICK_RATE_MS);
			if(rx_len >= 180){
				//Uart_protocol_decoding(rx_data,rx_len);
				ESP_LOGI(TAG,"\r\nrx_len = %d",rx_len);
				ESP_LOG_BUFFER_HEXDUMP(TAG,rx_data,rx_len,ESP_LOG_INFO);
				rx_len = 0;
			}
		}
}
void my_uart_init(void) {
	BaseType_t state = 0;
    const uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
    };
    // We won't use a buffer for sending data.
    uart_driver_install(EX_UART_NUM, RD1_BUF_SIZE * 2, RD1_BUF_SIZE * 2, 1024, &my_uart_queue, 0);
	//uart_driver_install(EX_UART_NUM, RD1_BUF_SIZE * 2, 0, 0, NULL, 0);
	//uart_driver_delete(EX_UART_NUM);
    uart_param_config(EX_UART_NUM, &uart_config);
    uart_set_pin(EX_UART_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    uart_pattern_queue_reset(UART_NUM_1, 1024);
    
    state = xTaskCreatePinnedToCore(uart_rx_task, "uart_rx_task", 1024*4, NULL, 3, NULL, 0);
    ESP_LOGI(TAG, "uart_rx_task create: 0x%x!!!",state);
	//state = xTaskCreatePinnedToCore(uart_tx_task, "uart_tx_task", 2048, NULL, 4, NULL, 0);
	//ESP_LOGI(TAG, "uart_tx_task create: 0x%x!!!",state);
}

